package com.winning.pmph.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.commons.lang3.StringUtils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 二维码工具类
 */
public class QrcodeUtils {

    static Map<EncodeHintType, Object> hints = new HashMap<>();
    //二维码宽度
    static final int QRWIDTH = 400;
    //二维码高度
    static final int QRHEIGHT = 400;
    //二维码名称高度
    static int QRNAMEHEIGHT = 20;
    //导出二维码 每张大图包含的二维码个数
    static int PAGECOUNT = 12;
    //大图每行多少个二维码
    static int COLS = 3;
    //大图二维码行数
    static int ROWS = PAGECOUNT % COLS == 0? PAGECOUNT / COLS : PAGECOUNT / COLS + 1;
    //大图包含的每个二维码之间的距离
    static int QRSPACE = 10;

    static {
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8);
        hints.put(EncodeHintType.MARGIN, 0);
    }

    /**
     * 生成二维码
     * @param qrUrl
     * @param qrName
     * @param logoPath
     * @param savePath
     * @throws Exception
     */
    public static void generateQrCode(String qrUrl, String qrName, String logoPath, String savePath) throws Exception {
        BufferedImage bim = getQrCodeBufferedImage(qrUrl, BarcodeFormat.QR_CODE, QRWIDTH, QRHEIGHT);
        addLogoToQrCode(bim, new File(logoPath), qrName, savePath);
    }

    public static void addLogoToQrCode(BufferedImage bim, File logoPic, String qrName, String savePath) throws Exception {
        Graphics2D g = bim.createGraphics();
        BufferedImage logo = ImageIO.read(logoPic);
        int widthLogo = Math.min(logo.getWidth(), bim.getWidth() * 3 / 10);
        int heightLogo = Math.min(logo.getHeight(), bim.getHeight() * 3 / 10);

        int x = (bim.getWidth() - widthLogo) / 2;
        int y = (bim.getHeight() - heightLogo) / 2;

        g.drawImage(logo, x, y, widthLogo, heightLogo, null);

        g.dispose();

        if (StringUtils.isNotBlank(qrName)) {
            BufferedImage outImage = new BufferedImage(QRWIDTH, QRHEIGHT + QRNAMEHEIGHT, BufferedImage.TYPE_4BYTE_ABGR);
            Graphics2D outg = outImage.createGraphics();

            outg.drawImage(bim, 0, QRNAMEHEIGHT, bim.getWidth(), bim.getHeight(), null);

            outg.setColor(Color.BLACK);
            outg.setFont(new Font("宋体", Font.PLAIN, 14));

            outg.drawString(qrName, 0, 14);

            outg.dispose();
            outImage.flush();
            bim = outImage;
        }
        logo.flush();
        bim.flush();
        File file = new File(savePath);
        if(!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        ImageIO.write(bim, "png", file);
    }

    public static BufferedImage getQrCodeBufferedImage(String content, BarcodeFormat barcodeFormat, int width, int height) throws Exception {
        BitMatrix bm = new MultiFormatWriter().encode(content, barcodeFormat, width, height, hints);
        int w = bm.getWidth();
        int h = bm.getHeight();
        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                image.setRGB(x, y, bm.get(x, y) ? -16777216 : -1);
            }
        }
        return image;
    }

    /**
     * 多个二维码放到一张大图里
     * @param qrPathList
     * @param savePath
     * @throws Exception
     */
    public static List<String> export(List<String> qrPathList, String savePath) throws Exception {
        List<String> paths = new ArrayList<>();
        int a4height = (QRHEIGHT + QRSPACE + QRNAMEHEIGHT)*ROWS + QRSPACE;
        int a4width = (QRWIDTH + QRSPACE)*COLS + QRSPACE;

        int jpgCount = qrPathList.size() % PAGECOUNT > 0 ? qrPathList.size() / PAGECOUNT + 1 :
                qrPathList.size() / PAGECOUNT;

        for (int j = 0; j < jpgCount; j++) {
            int end = j * PAGECOUNT + PAGECOUNT;
            if(end > qrPathList.size()) {
                end = qrPathList.size();
            }
            List<String> tmpList = qrPathList.subList(j * PAGECOUNT, end);
            BufferedImage ImageNew = new BufferedImage(a4width, a4height, BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics2d = ImageNew.createGraphics();
            ImageNew = graphics2d.getDeviceConfiguration().createCompatibleImage(a4width, a4height, Transparency.TRANSLUCENT);
            graphics2d.dispose();
            graphics2d = ImageNew.createGraphics();
            graphics2d.setColor(Color.BLACK);
            graphics2d.setBackground(Color.WHITE);
            graphics2d.setStroke(new BasicStroke(1));
            graphics2d.drawLine(0, 0, a4width, a4height);
            //释放对象
            graphics2d.dispose();

            for (int i = 0; i < tmpList.size(); i++) {

                File fileOne = new File(tmpList.get(i));
                BufferedImage ImageOne = ImageIO.read(fileOne);
                int width = ImageOne.getWidth();
                int height = ImageOne.getHeight();

                int[] ImageArrayOne = new int[width * height];
                ImageArrayOne = ImageOne.getRGB(0, 0, width, height,
                        ImageArrayOne, 0, width);
                int startX = (i % COLS) * width + (i % COLS + 1) * QRSPACE;
                int startY = (i / COLS) * height + (i / COLS + 1) * QRSPACE;
                ImageNew.setRGB(startX, startY, width, height, ImageArrayOne, 0, width);
            }
            Thread.sleep(1000L);
            String filePath = savePath.endsWith("/")?savePath:savePath+"/" + j + ".png";
            File outFile = new File(filePath);
            if(outFile.exists()) {
                outFile.delete();
            }else {
                outFile.getParentFile().mkdirs();
            }
            ImageIO.write(ImageNew, "png", outFile);
            paths.add(filePath);
        }
        return paths;
    }

    public static void main(String[] args) throws Exception {
        List<String> paths = new ArrayList<>();
        paths.add("/Users/yangjunhui/download/qrcode/1475343557768429569/chapterqr/1478552647604781057.png");
        paths.add("/Users/yangjunhui/download/qrcode/1475343557768429569/chapterqr/1478552647210516481.png");
        paths.add("/Users/yangjunhui/download/qrcode/1475343557768429569/chapterqr/1478552646023528450.png");
        paths.add("/Users/yangjunhui/download/qrcode/1475343557768429569/chapterqr/1478552645960613889.png");
        paths.add("/Users/yangjunhui/download/qrcode/1475343557768429569/chapterqr/1478552645897699330.png");
        paths.add("/Users/yangjunhui/download/qrcode/1475343557768429569/chapterqr/1478552645763481601.png");
        paths.add("/Users/yangjunhui/download/qrcode/1475343557768429569/chapterqr/1478552644119314435.png");
        export(paths, "/Users/yangjunhui/download/qrcode/1475343557768429569/export");
        //        generateQrCode("https://ccdas.pmphai.com", "标题一",
//                "/Users/yangjunhui/download/qrlogo/qr_video.png", "/Users/yangjunhui/download/qrcode/24.png");
    }
}